/**
 * 用户管理模块
 */
const router = require('koa-router')()
const User = require('./../models/userSchema')
const Menu = require('./../models/menuSchema')
const Role = require('./../models/roleSchema')
const Counter = require('./../models/counterSchema')
const util = require('./../utils/util')
const jwt = require('jsonwebtoken')
const md5 = require('md5')

// 添加二级路由
router.prefix('/users')

// 用户注册
router.post('/register', async (ctx) => {
  const { userName, userPwd } = ctx.request.body
  // console.log(ctx.request.body)
  try {
    // 查询用户名是否存在
    const existingUser = await User.findOne({userName})
    if(existingUser) {
      ctx.body = util.error("用户已存在")
    } else {
      const newUser = new User({ userName, userPwd })
      await newUser.save()
      ctx.body = util.success("注册成功")
    }
  } catch (error) {
    ctx.body = util.fail(error.msg)
  }
})

// 用户登录
router.post('/login', async (ctx) => {
  try {
    const { userName, userPwd } = ctx.request.body
    const res = await User.findOne({
      userName,
      userPwd
    }).select('userId userName userEmail state role deptId roleList')
    // res._doc返回用户的字段
    const data = res._doc
    // JWT生成token值
    // 令牌组成: 标头(Header)、 有效载荷(Payload) 签名(签名)
    const token = jwt.sign({
      data,
    },'imooc',{ expiresIn: '4h' })
    
    // console.log('token=>', token)
    if (res) {
      data.token = token
      ctx.body = util.success(data)
    } else {
      ctx.body = util.fail("账号或密码不正确")
    }
  } catch (error) {
    ctx.body = util.fail(error.msg)
  }
})

// 获取用户列表
router.get('/list', async (ctx) => {
  const { userId, userName, state } = ctx.request.query
  const { page,skipIndex } = util.pager(ctx.request.query)
  let params = {}
  if(userId)params.userId = userId
  if(userName)params.userName = userName
  if(state && state != '0')params.state = state
  // 根据条件查询所有用户列表
  try {
    const query = User.find(params, {_id:0,userPwd:0})
    const list =  await query.skip(skipIndex).limit(page.pageSize)
    const total = await User.countDocuments(params)
    
    ctx.body = util.success({
      page: {
        ...page,
        total
      },
      list
    })
  } catch (error) {

  }
})

// 获取全量用户列表
router.get('/all/list', async(ctx) => {
  try {
    const list = await User.find({}, "_id userId userName userEmail ")
    console.log('全量用户',list)
    ctx.body = util.success(list)
  } catch (error) {
    ctx.body = util.fail(error.stack)
  }
})

// 用户删除/批量删除
router.post('/delete', async (ctx) => {
  // 待删除的用户Id数组
  const { userIds } = ctx.request.body
  console.log('userIds',userIds)
  // 不真实删除用户在数据库的Ids,只修改用户的状态
  // User.updateMany({ $or: [{userId:10001},{userId:10002}] })
  const res = await User.updateMany({ userId: { $in: userIds } }, { state: 2 })
  // console.log('res=>',res)
  if (res) {
    ctx.body = util.success(res, '删除成功')
    return
  }
  ctx.body = util.fail('删除失败')
})

// 用户新增/编辑
router.post('/operate', async (ctx) => {
  const { userId, userName, userEmail, mobile, job, state, roleList, deptId, action } = ctx.request.body
  // 判断用户新增类型
  if( action == 'add' ) {
    if(!userName || !userEmail || !deptId) {
      ctx.body = util.fail('参数错误', util.CODE.PARAM_ERROR)
      return
    }
    
    // console.log('doc=>',doc)
    const res = await User.findOne({ $or: [{ userName }, {userEmail}] }, '_id userName userEmail')
    if(res) {
      ctx.body = util.fail(`系统检测到有重复的用户,信息如下: ${res.userName} - ${res.userEmail}`)
    }else{
      const doc = await Counter.findOneAndUpdate({ _id:'userId'}, {$inc: { sequence_value: 1 } }, { new: true})
      try {
        // 创建new对象
      const user = new User({
        userId:doc.sequence_value,
        userName,
        userPwd:md5('123456'),
        userEmail,
        role:1,
        roleList,
        job,
        state,
        deptId
      })
      user.save()
      ctx.body = util.success('','用户创建成功!')
      } catch (error) {
        ctx.body = util.fail(error,'用户创建成功!')
      }
    }
  }else {
    if(!deptId) {
      ctx.body = util.fail('部门不能为空', util.CODE.PARAM_ERROR)
    }
  }
  try{
    const res = await User.findOneAndUpdate({ userId },{mobile, job, state, roleList, deptId })
    ctx.body = util.success({},'更新成功!')
    return
  } catch (error) {
    ctx.body = util.fail(error.stack,'更新失败!')
  }
  
})

//获取用户对应的权限菜单
router.get('/getPermissionList', async(ctx) => {
  let authorization =  ctx.request.headers.authorization
  // 解密data数据
  let { data } = util.decoded(authorization)
  console.log(data,'data')
  let menuList = await getMenuList(data.role, data.roleList)
  // 对menuList深拷贝复制进行递归 
  let actionList = getActionList(JSON.parse(JSON.stringify(menuList)))
  ctx.body = util.success({menuList, actionList})
}) 

async function getMenuList (userRole, roleKeys) {
  // console.log(userRole,'1112')
  let rootList = []
  // 管理员权限
  if(userRole == 0) {
    rootList = await Menu.find({}) || []
    // console.log('rootList=>', rootList)
  } else {
    // 根据用户拥有的角色,获取权限列表
    // 查找用户对应的角色
    let roleList = await Role.find({_id: { $in: roleKeys }})
    let permissionList = []
    roleList.map(role => {
      let { checkedKeys, halfCheckedKeys } = role.permissionList
      permissionList = permissionList.concat([...checkedKeys, ...halfCheckedKeys])
    })
    // 权限去重
    permissionList = [...new Set(permissionList)]
    rootList = await Menu.find({ _id:{ $in: permissionList}})
  }
  return util.getTreeMenu(rootList, null, [])
}

// 递归按钮表单
function getActionList (list) {
  // 保存按钮
  const actionList = []
  const deep = (arr) => {
    while (arr.length) {
      let item = arr.pop()
      if (item.action) {
        item.action.map(action => {
          actionList.push(action.menuCode)
        })
      }
      if (item.children && !item.action) {
        deep(item.children)
      }
    }
  }
  deep(list)
  return actionList
}
module.exports = router
